/*******************************************************************************
  MPLAB Harmony Application Source File
  
  Company:
    Microchip Technology Inc.
  
  File Name:
    app2.c

  Summary:
    This file contains the source code for the MPLAB Harmony application.

  Description:
    This file contains the source code for the MPLAB Harmony application.  It 
    implements the logic of the application's state machine and it may call 
    API routines of other MPLAB Harmony modules in the system, such as drivers,
    system services, and middleware.  However, it does not call any of the
    system interfaces (such as the "Initialize" and "Tasks" functions) of any of
    the modules in the system or make any assumptions about when those functions
    are called.  That is the responsibility of the configuration-specific system
    files.
 *******************************************************************************/

// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright (c) 2013-2014 released Microchip Technology Inc.  All rights reserved.

Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).

You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.

SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
 *******************************************************************************/
// DOM-IGNORE-END


// *****************************************************************************
// *****************************************************************************
// Section: Included Files 
// *****************************************************************************
// *****************************************************************************

#include "app2.h"
#include "pcf8575.h"
#include "user_config.h"

// *****************************************************************************
// *****************************************************************************
// Section: Global Data Definitions
// *****************************************************************************
// *****************************************************************************

// *****************************************************************************
/* Application Data

  Summary:
    Holds application data

  Description:
    This structure holds the application's data.

  Remarks:
    This structure should be initialized by the APP_Initialize function.
    
    Application strings and buffers are be defined outside this structure.
 */

APP2_DATA app2Data;

uint16_t ad1_temp[5] = {0};
uint16_t ad2_temp[5] = {0};
uint16_t ADCValue_1 = 0;
uint16_t ADCValue_2 = 0;

// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************

/* TODO:  Add any necessary callback funtions.
 */

// *****************************************************************************
// *****************************************************************************
// Section: Application Local Functions
// *****************************************************************************
// *****************************************************************************

/* TODO:  Add any necessary local functions.
 */

//延时函数

void delay_ai(uint16_t num) {
    while (num--);

    return;
}

// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
  Function:
    void APP2_Initialize ( void )

  Remarks:
    See prototype in app2.h.
 */

void APP2_Initialize(void) {
    /* Place the App state machine in its initial state. */
    app2Data.state = APP2_STATE_INIT;

    /* TODO: Initialize your application's state machine and other
     * parameters.
     */
}

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  count_median_filter
 *  Description:  计算中值滤波值。
 * =====================================================================================
 */
void count_median_filter(void) {

    int i, j, temp;

    for (i = 1; i < 5; i++) {
        for (j = 0; j < 5 - i; j++) {
            if (ad1_temp[j] > ad1_temp[j + 1]) {
                temp = ad1_temp[j];
                ad1_temp[j] = ad1_temp[j + 1];
                ad1_temp[j + 1] = temp;
            }
//            if (ad2_temp[j] > ad2_temp[j + 1]) {
//                temp = ad2_temp[j];
//                ad2_temp[j] = ad2_temp[j + 1];
//                ad2_temp[j + 1] = temp;
//            }
        }
    }

    ADCValue_1 = ad1_temp[2];
//    ADCValue_2 = ad2_temp[2];

    return;
} /* -----  end of function count_median_filter  ----- */

//void get_ai2_value(void){
//
//	uint16_t value = 0;
//	uint16_t cal_lo = cal_para[CAL_OFS_AI2_LO];
//	uint16_t cal_hi = cal_para[CAL_OFS_AI2_HI];
//        uint16_t pro_lo = cfg_tbl[CFG_OFS_AI2_LO_VALUE];
//        uint16_t pro_hi = cfg_tbl[CFG_OFS_AI2_HI_VALUE];
//
//	value = ((1600 * ADCValue_2 + 400 * cal_hi - 2000 * cal_lo) / (cal_hi - cal_lo));
//
//	if ((value >= 100) && (value <= 3000)) { /*范围设定在2~30mA*/
//                mes_tbl[MES_OFS_AI_STATE] |= 0x0002;    //模拟量接入状态为接入
//		mes_tbl[MES_OFS_AI2_I] = value;
//		pcf8575_led_on(LED_HI_06);
//		//        PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//		//        printf("I2_Value:%d\r\n", value);
//		//        PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//                value = (((pro_hi - pro_lo) * ADCValue_2 + pro_lo * cal_hi - pro_hi * cal_lo) / (cal_hi - cal_lo));
////		value = ((5000 * ADCValue_2 - 5000 * cal_lo) / (cal_hi - cal_lo));
//		mes_tbl[MES_OFS_AI2_VALUE] = value;
//		//        PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//		//        printf("Freq2_Value:%d\r\n", value);
//		//        PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//	} else {
//                mes_tbl[MES_OFS_AI_STATE] &= (~0x0002);    //模拟量接入状态为非接入
//		mes_tbl[MES_OFS_AI2_I] = 0;
//		mes_tbl[MES_OFS_AI2_VALUE] = 0;
//		pcf8575_led_off(LED_HI_06);
//	}
//}

/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  get_freq_value
 *  Description:  通过AI1获得采集测量值。
 * =====================================================================================
 */
void get_ai1_value(void) {

	uint16_t value = 0;
	uint16_t cal_lo = cal_para[CAL_OFS_AI1_LO];
	uint16_t cal_hi = cal_para[CAL_OFS_AI1_HI];
        uint16_t pro_lo = cfg_tbl[CFG_OFS_AI1_LO_VALUE];
        uint16_t pro_hi = cfg_tbl[CFG_OFS_AI1_HI_VALUE];

        if((cal_hi - cal_lo) == 0){
            return;
        }

	value = ((1600 * ADCValue_1 + 400 * cal_hi - 2000 * cal_lo) / (cal_hi - cal_lo));
	if ((value >= 100) && (value <= 3000)) { /*范围设定在2~30mA*/
                mes_tbl[MES_OFS_AI_STATE] |= 0x0001;    //模拟量接入状态为接入
		mes_tbl[MES_0FS_AI1_I] = value;
		pcf8575_led_on(LED_HI_05);
		//        PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
		//        printf("I1_Value:%d\r\n", value);
		//        PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);

                value = (((pro_hi - pro_lo) * ADCValue_1 + pro_lo * cal_hi - pro_hi * cal_lo) / (cal_hi - cal_lo));
//		value = ((5000 * ADCValue_1 - 5000 * cal_lo) / (cal_hi - cal_lo));
		mes_tbl[MES_OFS_AI1_VALUE] = value;
                if((mes_tbl[MES_OFS_WELL_STATE] & 0x0004) == 0x0004){       //如果当前处于远程状态

                }else{                                                      //当前处于本地状态
                    cfg_tbl[CFG_OFS_FRE_RATE] = value;
                }
		//        PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
		//        printf("Freq1_Value:%d\r\n", value);
		//        PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
	} else {
                mes_tbl[MES_OFS_AI_STATE] &= (~0x0001);    //模拟量接入状态为非接入
		mes_tbl[MES_0FS_AI1_I] = 0;
		mes_tbl[MES_OFS_AI1_VALUE] = 0;
		pcf8575_led_off(LED_HI_05);
	}

	return;
} /* -----  end of function get_freq_value  ----- */

/******************************************************************************
  Function:
    void APP2_Tasks ( void )

  Remarks:
    See prototype in app2.h.
 */

void APP2_Tasks(void) {
    uint16_t i;
    //     uint16_t v_temp;
    //     uint16_t v_temp_i; /*整数部分*/
    //     uint16_t v_temp_d; /*小数部分*/
    //     uint16_t i_temp;
    //     uint16_t i_temp_i; /*整数部分*/
    //     uint16_t i_temp_d; /*小数部分*/

    /* Check the application's current state. */
    switch (app2Data.state) {
            /* Application's initial state. */
        case APP2_STATE_INIT:
        {
            for (i = 0; i < 5; i++) {
                IFS1bits.AD1IF = 0;
                AD1CON1bits.ASAM = 1; // auto start sampling
                // for 31Tad then go to conversion
                while (!IFS1bits.AD1IF); // conversion done?
                AD1CON1bits.ASAM = 0; // yes then stop sample/convert
                ad1_temp[i] = ADC1BUF0;
                ad2_temp[i] = ADC1BUF1;
            }
            count_median_filter(); /*中值滤波*/

//            PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
//            printf("V1_Value:%d\r\n", ADCValue_1);
//            printf("V2_Value:%d\r\n", ADCValue_2);
//            PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
            get_ai1_value();
//            get_ai2_value();

            //			PLIB_PORTS_PinSet(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
            //			v_temp = ((2500 * ADCValue_1)/1023);
            //			v_temp_i = v_temp/1000;
            //			v_temp_d = v_temp%1000;
            //			i_temp_i = v_temp/100;
            //			i_temp_d = v_temp%100;
            //			printf("V1_Value:%2d.%2d(V) I1_Value:%2d.%2d(mA)\r\n", v_temp_i, v_temp_d, i_temp_i, i_temp_d);
            //			v_temp = ((2500 * ADCValue_2)/1023);
            //			v_temp_i = v_temp/1000;
            //			v_temp_d = v_temp%1000;
            //			i_temp_i = v_temp/100;
            //			i_temp_d = v_temp%100;
            //			printf("V2_Value:%2d.%2d(V) I2_Value:%2d.%2d(mA)\r\n", v_temp_i, v_temp_d, i_temp_i, i_temp_d);
            //			PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_F, PORTS_BIT_POS_3);
            break;
        }

            /* TODO: implement your application state machine.*/

            /* The default state should never be executed. */
        default:
        {
            /* TODO: Handle error in application's state machine. */
            break;
        }
    }
}


/*******************************************************************************
 End of File
 */
